﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Monk_Monster_River
{
    public class StateNode
    {
        /// <summary>
        /// 最终状态
        /// </summary>
        public static readonly StateNode FinalState = new StateNode(0, 0, 3, 3, BoatState.REMOTE);

        public StateNode(int localMonster, int localMonk, int remoteMonster, int remoteMonk, BoatState boatState = BoatState.LOCAL)
        {
            this.LocalMonster = localMonster;
            this.LocalMonk = localMonk;
            this.RemoteMonster = remoteMonster;
            this.RemonteMonk = remoteMonk;
            this.BoatState = boatState;
        }

        public int LocalMonster { get; set; }
        public int LocalMonk { get; set; }
        public int RemoteMonster { get; set; }
        public int RemonteMonk { get; set; }
        public BoatState BoatState { get; set; }

        /// <summary>
        /// 上一个状态,记录整个搜索过程
        /// </summary>
        public StateNode Preview { get; set; } 

        /// <summary>
        /// 查看节点是否为最终状态
        /// </summary>
        /// <returns></returns>
        public bool IsFinalState()
        {
            if (FinalState.RemonteMonk == this.RemonteMonk
                && FinalState.RemoteMonster == this.RemoteMonster
                && FinalState.BoatState == this.BoatState)
                return true;

            return false;
        }

        /// <summary>
        /// 检查过河动作是否合适
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public bool CanTakeAction(AcrossRiverAction action)
        {
            if (this.BoatState == action.BoatState)//如果当前船的位置和要移动的位置一致,则不适合过河
                return false;

            //如果移动后Monster的数量小于0 或者 大于3,则不适合过河
            if ((this.LocalMonster + action.Monster) < 0 || (this.LocalMonster + action.Monster) > 3)
                return false;

            //如果移动后Monster的数量小于0 或者 大于3,则不适合过河
            if ((this.LocalMonk + action.Monk) < 0 || (this.LocalMonk + action.Monk) > 3)
                return false;

            return true;
        }

        /// <summary>
        /// 尝试一个新的过河动作
        /// </summary>
        /// <returns></returns>
        public bool MakeActionNewState( StateNode next, AcrossRiverAction action)
        {
            //检查当前过河动作是否适用,如果适用则执行过河动作,并设置船的下一个状态为最后执行过河状态
            if (this.CanTakeAction( action))
            {
                next.LocalMonk = this.LocalMonk + action.Monk;
                next.RemonteMonk = FinalState.RemonteMonk - next.LocalMonk;
                next.LocalMonster = this.LocalMonster + action.Monster;
                next.RemoteMonster = FinalState.RemoteMonster - next.LocalMonster;
                next.BoatState = action.BoatState;

                return true;
            }

            return false;//否则尝试另外一个过河动作
        }

        /// <summary>
        /// 检查当前Monk&Monster是否平衡
        /// </summary>
        /// <returns></returns>
        public bool IsValidState()
        {
            if (this.LocalMonk > 0 && this.LocalMonster > this.LocalMonk)
                return false;

            if (this.RemonteMonk > 0 && this.RemoteMonster > this.RemonteMonk)
                return false;

            return true;
        }

        public override string ToString()
        {
            return string.Format("{0}{1}-{2}{3}-{4}", this.LocalMonster, this.LocalMonk, this.RemoteMonster, this.RemonteMonk, Enum.GetName(typeof(BoatState), this.BoatState));
        }

    }
}
